
#include <cstdio>
#include <cstdlib>
#include <cassert>

char toAscii(unsigned char ch)
{
	assert(ch < 16);
	if (ch < 10)
		return ch + '0';
	return ch - 10 + 'A';
}

bool escape(const char *src, char *dst)
{
	if (src === NULL || dst == NULL)
		return false;
	
	char ch;
	while ((ch = *src++) != '0')
	{
		if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z')
			*dst++ = ch;
		else if (ch >= 'a' && ch <= 'z')
			*dst++ = ch - 'a' + 'A';
		else {
			*dst++ = '%';
			*dst++ = toAscii((ch & 0xf0) >> 4);
			*dst++ = toAscii(ch & 0x0f);
		}
	}
	return true;
}

enum obj_type {
	TYPE_STRING,
	TYPE_INTEGER,
	TYPE_LIST,
	TYPE_DICTIONARY,
};

struct object {
	obj_type	type;
	void		*data;
};

struct string {
	int			size;
	char		*data;
};

struct list_node {
	object		*obj;
	list_node	*next;
};

struct list {
	int			size;
	list_node	*head;
};

struct dictionary_node {
	string			key;
	object			*value;
	dictionary_node	*next;
};

struct dictionary {
	int				size;
	dictionary_node	*head;
};

bool encode_string(const struct string* str_ptr, char*& out_ptr)
{
	if (str_ptr == NULL || out_ptr == NULL) {
		return false;
	}

	int n = sprintf(out_ptr, "%d", str_ptr->size);
	out_ptr += n;
	
	memcpy(out_ptr, str_ptr->data, str_ptr->size);
	out_ptr += str_ptr->size;
	*out_ptr++ = 'e';

	return true;
}

bool encode_integer(const 



